package com.cencat.common.utils;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;

import java.util.List;

/**
 * 分页工具类
 * 提供分页相关的工具方法和通用分页结果封装
 * 
 * @author cencat
 * @since 2024-01-01
 */
public class PageUtils {

    /**
     * 私有构造函数，防止实例化
     */
    private PageUtils() {
        throw new UnsupportedOperationException("Utility class cannot be instantiated");
    }

    /**
     * 默认页码
     */
    public static final long DEFAULT_CURRENT = 1L;

    /**
     * 默认每页大小
     */
    public static final long DEFAULT_SIZE = 10L;

    /**
     * 最大每页大小
     */
    public static final long MAX_SIZE = 1000L;

    /**
     * 创建分页对象
     * 
     * @param current 当前页码
     * @param size 每页大小
     * @param <T> 泛型类型
     * @return 分页对象
     */
    public static <T> Page<T> createPage(Long current, Long size) {
        // 参数校验
        if (current == null || current < 1) {
            current = DEFAULT_CURRENT;
        }
        if (size == null || size < 1) {
            size = DEFAULT_SIZE;
        }
        if (size > MAX_SIZE) {
            size = MAX_SIZE;
        }
        
        return new Page<>(current, size);
    }

    /**
     * 创建分页对象（使用默认参数）
     * 
     * @param <T> 泛型类型
     * @return 分页对象
     */
    public static <T> Page<T> createPage() {
        return createPage(DEFAULT_CURRENT, DEFAULT_SIZE);
    }

    /**
     * 转换分页结果
     * 
     * @param page 原始分页对象
     * @param <T> 泛型类型
     * @return 分页结果
     */
    public static <T> PageResult<T> convertPageResult(IPage<T> page) {
        PageResult<T> result = new PageResult<>();
        result.setCurrent(page.getCurrent());
        result.setSize(page.getSize());
        result.setTotal(page.getTotal());
        result.setPages(page.getPages());
        result.setRecords(page.getRecords());
        result.setHasNext(page.getCurrent() < page.getPages());
        result.setHasPrevious(page.getCurrent() > 1);
        return result;
    }

    /**
     * 计算总页数
     * 
     * @param total 总记录数
     * @param size 每页大小
     * @return 总页数
     */
    public static long calculatePages(long total, long size) {
        if (size <= 0) {
            return 0;
        }
        return (total + size - 1) / size;
    }

    /**
     * 计算偏移量
     * 
     * @param current 当前页码
     * @param size 每页大小
     * @return 偏移量
     */
    public static long calculateOffset(long current, long size) {
        if (current <= 0) {
            current = 1;
        }
        return (current - 1) * size;
    }

    /**
     * 分页结果封装类
     * 
     * @param <T> 数据类型
     */
    public static class PageResult<T> {
        
        /**
         * 当前页码
         */
        private long current;
        
        /**
         * 每页大小
         */
        private long size;
        
        /**
         * 总记录数
         */
        private long total;
        
        /**
         * 总页数
         */
        private long pages;
        
        /**
         * 当前页数据
         */
        private List<T> records;
        
        /**
         * 是否有下一页
         */
        private boolean hasNext;
        
        /**
         * 是否有上一页
         */
        private boolean hasPrevious;
        
        // Getter and Setter methods
        public long getCurrent() {
            return current;
        }
        
        public void setCurrent(long current) {
            this.current = current;
        }
        
        public long getSize() {
            return size;
        }
        
        public void setSize(long size) {
            this.size = size;
        }
        
        public long getTotal() {
            return total;
        }
        
        public void setTotal(long total) {
            this.total = total;
        }
        
        public long getPages() {
            return pages;
        }
        
        public void setPages(long pages) {
            this.pages = pages;
        }
        
        public List<T> getRecords() {
            return records;
        }
        
        public void setRecords(List<T> records) {
            this.records = records;
        }
        
        public boolean isHasNext() {
            return hasNext;
        }
        
        public void setHasNext(boolean hasNext) {
            this.hasNext = hasNext;
        }
        
        public boolean isHasPrevious() {
            return hasPrevious;
        }
        
        public void setHasPrevious(boolean hasPrevious) {
            this.hasPrevious = hasPrevious;
        }

        /**
         * 是否为第一页
         */
        public boolean isFirst() {
            return current <= 1;
        }

        /**
         * 是否为最后一页
         */
        public boolean isLast() {
            return current >= pages;
        }

        /**
         * 是否为空页
         */
        public boolean isEmpty() {
            return records == null || records.isEmpty();
        }

        /**
         * 获取记录数量
         */
        public int getRecordCount() {
            return records == null ? 0 : records.size();
        }

        /**
         * 创建Builder实例
         * @param <T> 数据类型
         * @return Builder实例
         */
        public static <T> Builder<T> builder() {
            return new Builder<>();
        }
        
        /**
         * PageResult构建器
         * @param <T> 数据类型
         */
        public static class Builder<T> {
            private long current;
            private long size;
            private long total;
            private long pages;
            private List<T> data;
            private boolean hasNext;
            private boolean hasPrevious;
            
            public Builder<T> current(long current) {
                this.current = current;
                return this;
            }
            
            public Builder<T> size(long size) {
                this.size = size;
                return this;
            }
            
            public Builder<T> total(long total) {
                this.total = total;
                return this;
            }
            
            public Builder<T> pages(long pages) {
                this.pages = pages;
                return this;
            }
            
            public Builder<T> data(List<T> data) {
                this.data = data;
                return this;
            }
            
            public Builder<T> records(List<T> records) {
                this.data = records;
                return this;
            }
            
            public Builder<T> hasNext(boolean hasNext) {
                this.hasNext = hasNext;
                return this;
            }
            
            public Builder<T> hasPrevious(boolean hasPrevious) {
                this.hasPrevious = hasPrevious;
                return this;
            }
            
            public Builder<T> pageNum(int pageNum) {
                this.current = pageNum;
                return this;
            }
            
            public Builder<T> pageSize(int pageSize) {
                this.size = pageSize;
                return this;
            }
            
            public PageResult<T> build() {
                PageResult<T> result = new PageResult<>();
                result.setCurrent(this.current);
                result.setSize(this.size);
                result.setTotal(this.total);
                result.setPages(this.pages);
                result.setRecords(this.data);
                result.setHasNext(this.hasNext);
                result.setHasPrevious(this.hasPrevious);
                return result;
            }
        }
    }

    /**
     * 分页查询参数
     */
    public static class PageQuery {
        /**
         * 当前页码
         */
        private Long current = DEFAULT_CURRENT;

        /**
         * 每页大小
         */
        private Long size = DEFAULT_SIZE;

        /**
         * 排序字段
         */
        private String orderBy;

        /**
         * 排序方向：ASC/DESC
         */
        private String orderDirection = "ASC";

        public Long getCurrent() {
            return current;
        }

        public void setCurrent(Long current) {
            this.current = current;
        }

        public Long getSize() {
            return size;
        }

        public void setSize(Long size) {
            this.size = size;
        }

        public String getOrderBy() {
            return orderBy;
        }

        public void setOrderBy(String orderBy) {
            this.orderBy = orderBy;
        }

        public String getOrderDirection() {
            return orderDirection;
        }

        public void setOrderDirection(String orderDirection) {
            this.orderDirection = orderDirection;
        }

        /**
         * 转换为MyBatis-Plus分页对象
         * 
         * @param <T> 泛型类型
         * @return 分页对象
         */
        public <T> Page<T> toPage() {
            Page<T> page = PageUtils.createPage(current, size);
            
            // 设置排序
            if (CencatStringUtils.isNotBlank(orderBy)) {
                if ("DESC".equalsIgnoreCase(orderDirection)) {
                    page.addOrder(OrderItem.desc(orderBy));
                } else {
                    page.addOrder(OrderItem.asc(orderBy));
                }
            }
            
            return page;
        }
    }
}